home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 1: Comms & Networking / Almathera Ten on Ten - Disc 1: Comms & Networking.iso / amiga-useful / perl / src / array.c < prev    next >
C/C++ Source or Header  |  1995-05-04  |  6KB  |  314 lines

  1. /* $RCSfile: array.c,v $$Revision: 4.0.1.3 $$Date: 92/06/08 11:45:05 $
  2.  *
  3.  *    Copyright (c) 1991, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    array.c,v $
  9.  * Revision 4.0.1.3  92/06/08  11:45:05  lwall
  10.  * patch20: Perl now distinguishes overlapped copies from non-overlapped
  11.  * 
  12.  * Revision 4.0.1.2  91/11/05  16:00:14  lwall
  13.  * patch11: random cleanup
  14.  * patch11: passing non-existend array elements to subrouting caused core dump
  15.  * 
  16.  * Revision 4.0.1.1  91/06/07  10:19:08  lwall
  17.  * patch4: new copyright notice
  18.  * 
  19.  * Revision 4.0  91/03/20  01:03:32  lwall
  20.  * 4.0 baseline.
  21.  * 
  22.  */
  23.  
  24. #include "EXTERN.h"
  25. #include "perl.h"
  26.  
  27. #if defined(AMIGA) && defined(DEBUGGING)
  28. STR *amiafetch(ar,key,lval, line, file)
  29. int line;
  30. char *file;
  31. #else
  32. STR *
  33. afetch(ar,key,lval)
  34. #endif
  35. register ARRAY *ar;
  36. int key;
  37. int lval;
  38. {
  39.     STR *str;
  40.  
  41. #if defined(AMIGA) && defined(DEBUGGING)
  42.     if(debug&16384) fprintf(stderr, "Called afetch with key = %d @line %d in %s\n   ary_fill = %d\n", 
  43.         key,line,file,ar->ary_fill);
  44. #endif
  45.  
  46.     if (key < 0 || key > ar->ary_fill) {
  47.     if (lval && key >= 0) {
  48.         if (ar->ary_flags & ARF_REAL)
  49.         str = Str_new(5,0);
  50.         else
  51.         str = str_mortal(&str_undef);
  52.         (void)astore(ar,key,str);
  53.         return str;
  54.     }
  55.     else
  56.         return &str_undef;
  57.     }
  58.     if (!ar->ary_array[key]) {
  59.     if (lval) {
  60.         str = Str_new(6,0);
  61.         (void)astore(ar,key,str);
  62.         return str;
  63.     }
  64.     return &str_undef;
  65.     }
  66.     return ar->ary_array[key];
  67. }
  68.  
  69. bool
  70. #if defined(AMIGA) && defined(DEBUGGING)
  71. amiastore(ar,key,val,line,file)
  72. int line;char *file;
  73. #else
  74. astore(ar,key,val)
  75. #endif
  76. register ARRAY *ar;
  77. int key;
  78. STR *val;
  79. {
  80.     int retval;
  81.  
  82. #if defined(AMIGA) && defined(DEBUGGING)
  83.     if(debug&16384)fprintf(stderr,"Calling astore @line %d of file %s\n",
  84.                line, file );
  85. #endif               
  86.  
  87.     if (key < 0)
  88.     return FALSE;
  89.     if (key > ar->ary_max) {
  90.     int newmax;
  91.  
  92.     if (ar->ary_alloc != ar->ary_array) {
  93.         retval = ar->ary_array - ar->ary_alloc;
  94.         Move(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
  95.         Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
  96.         ar->ary_max += retval;
  97.         ar->ary_array -= retval;
  98.         if (key > ar->ary_max - 10) {
  99.         newmax = key + ar->ary_max;
  100.         goto resize;
  101.         }
  102.     }
  103.     else {
  104.         if (ar->ary_alloc) {
  105.         newmax = key + ar->ary_max / 5;
  106.           resize:
  107.         Renew(ar->ary_alloc,newmax+1, STR*);
  108.         Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
  109.         }
  110.         else {
  111.         newmax = key < 4 ? 4 : key;
  112.  
  113. #if defined(AMIGA) && defined(DEBUGGING)
  114.         if(debug&16384) {
  115.             fprintf(stderr, "astoring: newmax %d, oldmax %d\n",
  116.                 newmax, ar->ary_max);
  117.         }
  118. #endif
  119.  
  120.         Newz(2,ar->ary_alloc, newmax+1, STR*);
  121.         }
  122.         ar->ary_array = ar->ary_alloc;
  123.         ar->ary_max = newmax;
  124.     }
  125.     }
  126.     if (ar->ary_flags & ARF_REAL) {
  127.     if (ar->ary_fill < key) {
  128.         while (++ar->ary_fill < key) {
  129.         if (ar->ary_array[ar->ary_fill] != Nullstr) {
  130.             str_free(ar->ary_array[ar->ary_fill]);
  131.             ar->ary_array[ar->ary_fill] = Nullstr;
  132.         }
  133.         }
  134.     }
  135.     retval = (ar->ary_array[key] != Nullstr);
  136.     if (retval)
  137.         str_free(ar->ary_array[key]);
  138.     }
  139.     else
  140.     retval = 0;
  141.     ar->ary_array[key] = val;
  142.     return retval;
  143. }
  144.  
  145. ARRAY *
  146. anew(stab)
  147. STAB *stab;
  148. {
  149.     register ARRAY *ar;
  150.  
  151.     New(1,ar,1,ARRAY);
  152.     ar->ary_magic = Str_new(7,0);
  153.     ar->ary_alloc = ar->ary_array = 0;
  154.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  155.     ar->ary_max = ar->ary_fill = -1;
  156.     ar->ary_flags = ARF_REAL;
  157.     return ar;
  158. }
  159.  
  160. ARRAY *
  161. afake(stab,size,strp)
  162. STAB *stab;
  163. register int size;
  164. register STR **strp;
  165. {
  166.     register ARRAY *ar;
  167.  
  168.     New(3,ar,1,ARRAY);
  169.     New(4,ar->ary_alloc,size+1,STR*);
  170.     Copy(strp,ar->ary_alloc,size,STR*);
  171.     ar->ary_array = ar->ary_alloc;
  172.     ar->ary_magic = Str_new(8,0);
  173.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  174.     ar->ary_fill = size - 1;
  175.     ar->ary_max = size - 1;
  176.     ar->ary_flags = 0;
  177.     while (size--) {
  178.     if (*strp)
  179.         (*strp)->str_pok &= ~SP_TEMP;
  180.     strp++;
  181.     }
  182.     return ar;
  183. }
  184.  
  185. void
  186. aclear(ar)
  187. register ARRAY *ar;
  188. {
  189.     register int key;
  190.  
  191.     if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
  192.     return;
  193.     /*SUPPRESS 560*/
  194.     if (key = ar->ary_array - ar->ary_alloc) {
  195.     ar->ary_max += key;
  196.     ar->ary_array -= key;
  197.     }
  198.     for (key = 0; key <= ar->ary_max; key++)
  199.     str_free(ar->ary_array[key]);
  200.     ar->ary_fill = -1;
  201.     Zero(ar->ary_array, ar->ary_max+1, STR*);
  202. }
  203.  
  204. void
  205. afree(ar)
  206. register ARRAY *ar;
  207. {
  208.     register int key;
  209.  
  210.     if (!ar)
  211.     return;
  212.     /*SUPPRESS 560*/
  213.     if (key = ar->ary_array - ar->ary_alloc) {
  214.     ar->ary_max += key;
  215.     ar->ary_array -= key;
  216.     }
  217.     if (ar->ary_flags & ARF_REAL) {
  218.     for (key = 0; key <= ar->ary_max; key++)
  219.         str_free(ar->ary_array[key]);
  220.     }
  221.     str_free(ar->ary_magic);
  222.     Safefree(ar->ary_alloc);
  223.     Safefree(ar);
  224. }
  225.  
  226. bool
  227. apush(ar,val)
  228. register ARRAY *ar;
  229. STR *val;
  230. {
  231.     return astore(ar,++(ar->ary_fill),val);
  232. }
  233.  
  234. STR *
  235. apop(ar)
  236. register ARRAY *ar;
  237. {
  238.     STR *retval;
  239.  
  240.     if (ar->ary_fill < 0)
  241.     return Nullstr;
  242.     retval = ar->ary_array[ar->ary_fill];
  243.     ar->ary_array[ar->ary_fill--] = Nullstr;
  244.     return retval;
  245. }
  246.  
  247. void
  248. aunshift(ar,num)
  249. register ARRAY *ar;
  250. register int num;
  251. {
  252.     register int i;
  253.     register STR **sstr,**dstr;
  254.  
  255.     if (num <= 0)
  256.     return;
  257.     if (ar->ary_array - ar->ary_alloc >= num) {
  258.     ar->ary_max += num;
  259.     ar->ary_fill += num;
  260.     while (num--)
  261.         *--ar->ary_array = Nullstr;
  262.     }
  263.     else {
  264.     (void)astore(ar,ar->ary_fill+num,(STR*)0);    /* maybe extend array */
  265.     dstr = ar->ary_array + ar->ary_fill;
  266.     sstr = dstr - num;
  267. #ifdef BUGGY_MSC5
  268.  # pragma loop_opt(off)    /* don't loop-optimize the following code */
  269. #endif /* BUGGY_MSC5 */
  270.     for (i = ar->ary_fill - num; i >= 0; i--) {
  271.         *dstr-- = *sstr--;
  272. #ifdef BUGGY_MSC5
  273.  # pragma loop_opt()    /* loop-optimization back to command-line setting */
  274. #endif /* BUGGY_MSC5 */
  275.     }
  276.     Zero(ar->ary_array, num, STR*);
  277.     }
  278. }
  279.  
  280. STR *
  281. ashift(ar)
  282. register ARRAY *ar;
  283. {
  284.     STR *retval;
  285.  
  286.     if (ar->ary_fill < 0)
  287.     return Nullstr;
  288.     retval = *ar->ary_array;
  289.     *(ar->ary_array++) = Nullstr;
  290.     ar->ary_max--;
  291.     ar->ary_fill--;
  292.     return retval;
  293. }
  294.  
  295. int
  296. alen(ar)
  297. register ARRAY *ar;
  298. {
  299.     return ar->ary_fill;
  300. }
  301.  
  302. void
  303. afill(ar, fill)
  304. register ARRAY *ar;
  305. int fill;
  306. {
  307.     if (fill < 0)
  308.     fill = -1;
  309.     if (fill <= ar->ary_max)
  310.     ar->ary_fill = fill;
  311.     else
  312.     (void)astore(ar,fill,Nullstr);
  313. }
  314.